//
//  BEProtocols.swift
//  BasicExtensions
//
//  Created by JY_NEW on 2022/9/3.
//

import Foundation

/// 可空
public protocol BEEmptiable {
    var isEmpty: Bool { get }
}
extension String: BEEmptiable { }
extension Array: BEEmptiable { }
extension Dictionary: BEEmptiable { }

/// 可计算弧度
public protocol BERadiansComputable: ExpressibleByIntegerLiteral {
    static var pi: Self { get }
    static func + (lhs: Self, rhs: Self) -> Self
    static func - (lhs: Self, rhs: Self) -> Self
    static func * (lhs: Self, rhs: Self) -> Self
    static func / (lhs: Self, rhs: Self) -> Self
}
extension Float: BERadiansComputable {}
@available(iOS 14.0, *)
extension Float16: BERadiansComputable { }
extension Double: BERadiansComputable { }
extension CGFloat: BERadiansComputable { }

/// 可计算+=操作
public protocol BEAddable {
    static func + (lhs: Self, rhs: Self) -> Self
}
extension String: BEAddable { }
extension Array: BEAddable { }
extension Dictionary: BEAddable {
    public static func + (lhs: Dictionary<Key, Value>, rhs: Dictionary<Key, Value>) -> Dictionary<Key, Value> {
        return lhs.merging(rhs, uniquingKeysWith: { _, v2 in v2 })
    }
}
extension CChar: BEAddable { }
extension UInt8: BEAddable { }
extension UInt16: BEAddable { }
extension UInt64: BEAddable { }
extension Float: BEAddable { }
extension Int32: BEAddable { }
extension Double: BEAddable { }
extension Int16: BEAddable { }
extension UInt32: BEAddable { }
extension Int: BEAddable { }
extension UInt: BEAddable { }
extension Int64: BEAddable { }
extension Decimal: BEAddable { }
extension CGFloat: BEAddable { }

/// 可解码类型
public protocol BEDecodable {
    static func decode(for coder: NSCoder, key: String) -> Self
}
/// 可解码类型且可为空
public protocol BEMaybeDecodable {
    static func decode(for coder: NSCoder, key: String) -> Self?
}

/// 可序列化化
public protocol BESerializable {
    /// 序列化
    func serialize() throws -> Data
    /// 反序列化
    static func deserialize(_ data: Data) throws -> Self
}
public protocol BEElementSerializable {
    associatedtype Element
    /// 从Data反序列化元素
    func element(for data: Data) throws -> Element
    /// 将元素序列化成Data
    func data(for element: Element) throws -> Data
}
